home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / exec / allocate.c < prev    next >
C/C++ Source or Header  |  1996-10-24  |  4KB  |  178 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: allocate.c,v 1.7 1996/10/24 15:50:43 aros Exp $
  4.     $Log: allocate.c,v $
  5.     Revision 1.7  1996/10/24 15:50:43  aros
  6.     Use the official AROS macros over the __AROS versions.
  7.  
  8.     Revision 1.6  1996/10/19 17:07:24  aros
  9.     Include <aros/machine.h> instead of machine.h
  10.  
  11.     Revision 1.5  1996/09/13 17:51:21  digulla
  12.     Use IPTR
  13.  
  14.     Revision 1.4  1996/08/13 13:55:57  digulla
  15.     Replaced AROS_LA by AROS_LHA
  16.     Replaced some AROS_LH*I by AROS_LH*
  17.     Sorted and added includes
  18.  
  19.     Revision 1.3  1996/08/01 17:41:04  digulla
  20.     Added standard header for all files
  21.  
  22.     Desc:
  23.     Lang:
  24. */
  25. #include "exec_intern.h"
  26. #include "memory.h"
  27. #include <aros/machine.h>
  28. #include <exec/alerts.h>
  29. #include <aros/libcall.h>
  30.  
  31. /*****************************************************************************
  32.  
  33.     NAME */
  34.     #include <exec/memory.h>
  35.     #include <clib/exec_protos.h>
  36.  
  37. AROS_LH2(APTR, Allocate,
  38.  
  39. /*  SYNOPSIS */
  40.     AROS_LHA(struct MemHeader *, freeList, A0),
  41.     AROS_LHA(ULONG,              byteSize, D0),
  42.  
  43. /*  LOCATION */
  44.     struct ExecBase *, SysBase, 31, Exec)
  45.  
  46. /*  FUNCTION
  47.     Allocate memory out of a private region handled by the MemHeader
  48.     structure.
  49.  
  50.     INPUTS
  51.     freeList - Pointer to the MemHeader structure which holds the memory
  52.     byteSize - Number of bytes you want to get
  53.  
  54.     RESULT
  55.     A pointer to the number of bytes you wanted or NULL if the memory
  56.     couldn't be allocated
  57.  
  58.     NOTES
  59.     The memory is aligned to sizeof(struct MemChunk). All requests
  60.     are rounded up to a multiple of that size.
  61.  
  62.     EXAMPLE
  63.     #define POOLSIZE 4096
  64.     \* Get a MemHeader structure and some private memory *\
  65.     mh=(struct MemHeader *)
  66.         AllocMem(sizeof(struct MemHeader)+POOLSIZE,MEMF_ANY);
  67.     if(mh!=NULL)
  68.     {
  69.         \* Build a private pool *\
  70.         mh->mh_First=(struct MemChunk *)(mh+1);
  71.         mh->mh_First->mc_Next=NULL;
  72.         mh->mh_First->mc_Bytes=POOLSIZE;
  73.         mh->mh_Free=POOLSIZE;
  74.         {
  75.         \* Use the pool *\
  76.         UBYTE *mem1,*mem2;
  77.         mem1=Allocate(mh,1000);
  78.         mem2=Allocate(mh,2000);
  79.         \* Do something with memory... *\
  80.         }
  81.         \* Free everything at once *\
  82.         FreeMem(mh,sizeof(struct MemHeader)+POOLSIZE);
  83.     }
  84.  
  85.     BUGS
  86.  
  87.     SEE ALSO
  88.     Deallocate()
  89.  
  90.     INTERNALS
  91.  
  92.     HISTORY
  93.     17-09-95    created by m. fleischer
  94.     16-10-95    increased portability
  95.  
  96. ******************************************************************************/
  97. {
  98.     AROS_LIBFUNC_INIT
  99.     struct MemChunk *p1, *p2;
  100.  
  101.     /* Zero bytes requested? May return everything ;-). */
  102.     if(!byteSize)
  103.     return NULL;
  104.  
  105.     /* First round byteSize to a multiple of MEMCHUNK_TOTAL. */
  106.     byteSize=(byteSize+MEMCHUNK_TOTAL-1)&~(MEMCHUNK_TOTAL-1);
  107.  
  108.     /* Is there enough free memory in the list? */
  109.     if(freeList->mh_Free<byteSize)
  110.     return NULL;
  111.  
  112.     /*
  113.     The free memory list is only single linked, i.e. to remove
  114.     elements from the list I need the node as well as it's
  115.     predessor. For the first element I can use freeList->mh_First
  116.     instead of a real predessor.
  117.     */
  118.     p1=(struct MemChunk *)&freeList->mh_First;
  119.     p2=p1->mc_Next;
  120.  
  121.     /* Is the list enpty? */
  122.     if(p2==NULL)
  123.     return NULL;
  124.  
  125.     /* Follow the list */
  126.     for(;;)
  127.     {
  128. #if !defined(NO_CONSISTENCY_CHECKS)
  129.     /* Consistency check: Check alignment restrictions */
  130.     if( ((IPTR)p2|(ULONG)p2->mc_Bytes) & (MEMCHUNK_TOTAL-1) )
  131.     {
  132.         Alert(AN_MemCorrupt);
  133.         return NULL;
  134.     }
  135. #endif
  136.     /* Check if current block is large enough */
  137.     if(p2->mc_Bytes>=byteSize)
  138.     {
  139.         /* It is. Remove it from the list and return it. */
  140.         if(p2->mc_Bytes==byteSize)
  141.         /* Fits exactly. Just relink the list. */
  142.         p1->mc_Next=p2->mc_Next;
  143.         else
  144.         {
  145.         /* Split the current chunk and return the first bytes. */
  146.         p1->mc_Next=(struct MemChunk *)((UBYTE *)p2+byteSize);
  147.         p1=p1->mc_Next;
  148.         p1->mc_Next=p2->mc_Next;
  149.         p1->mc_Bytes=p2->mc_Bytes-byteSize;
  150.         }
  151.         /* Adjust free memory count and return */
  152.         freeList->mh_Free-=byteSize;
  153.         return p2;
  154.     }
  155.  
  156.     /* Go to next block */
  157.     p1=p2;
  158.     p2=p1->mc_Next;
  159.  
  160.     /* Check if this was the end */
  161.     if(p2==NULL)
  162.         return NULL;
  163. #if !defined(NO_CONSISTENCY_CHECKS)
  164.     /*
  165.         Consistency check:
  166.         If the end of the last block+1 is bigger or equal to
  167.         the start of the current block something must be wrong.
  168.     */
  169.     if((UBYTE *)p2<=(UBYTE *)p1+p1->mc_Bytes)
  170.     {
  171.         Alert(AN_MemCorrupt);
  172.         return NULL;
  173.     }
  174. #endif
  175.     }
  176.     AROS_LIBFUNC_EXIT
  177. } /* Allocate */
  178.